package com.security.demo;


import com.security.encrypt.EncryptUtils;

import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


/**
 * AESUtils
 *
 * @author bianrongjun
 * @version 1.0
 */
public class AESUtils {
    public static final String AES_KEY = "90628114";
    public static String MODEL_ECB_PKCS5Padding = "AES/ECB/PKCS5Padding";
    public static String MODEL_CBC_PKCS5Padding = "AES/CBC/PKCS5Padding";
    public static String MODEL = MODEL_ECB_PKCS5Padding;

    public static byte[] encryptToBytes(String password, String content, String charset, String model, byte[] iv) {
        try {
            Cipher cipher = Cipher.getInstance(model);
            if (iv != null) {
                IvParameterSpec ivPs = new IvParameterSpec(iv);
                cipher.init(1, getKey(password), ivPs);
            } else {
                cipher.init(1, getKey(password));
            }
            return cipher.doFinal(content.getBytes("UTF-8"));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * encrypt
     *
     * @param content
     * @return
     * @throws Exception
     */
    public static String encrypt(String content) {
        try {
            String password = fixPassword16(AESUtils.AES_KEY);
            String e = EncryptUtils.getInstance().e(password, content, MODEL, null);
//            String e = encrypt(password, content, MODEL, null);

//            return e.replaceAll("\\+", "%2B");
            return URLEncoder.encode(e);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return content;
    }

    /**
     * encrypt
     *
     * @param password
     * @param content
     * @param model
     * @param iv
     * @return
     */
    public static String encrypt(String password, String content, String model, byte[] iv) {
        return Base64Utils.encode(encryptToBytes(password, content, "UTF-8", model, iv));
    }

    /**
     * decrypt
     *
     * @param content
     * @return
     * @throws Exception
     */
    public static String decrypt(String content) {
        try {
            String password16 = fixPassword16(AESUtils.AES_KEY);
            // FIXME: 2020/8/12 0012 记得删除
//            password16 = "8829463400000000";
            String d = EncryptUtils.getInstance().d(password16, URLDecoder.decode(content), MODEL, null);
//            String d = decrypt(password16, URLDecoder.decode(content), MODEL, null);
            return d;
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return content;
    }

    /**
     * decrypt
     *
     * @param password
     * @param content
     * @param model
     * @param iv
     * @return
     */
    public static String decrypt(String password, String content, String model, byte[] iv) {
        return decryptByBytes(password, Base64Utils.decode(content), "UTF-8", model, iv);
    }

    /**
     * decryptByBytes
     *
     * @param password
     * @param content
     * @param charset
     * @param model
     * @param iv
     * @return
     */
    public static String decryptByBytes(String password, byte[] content, String charset, String model, byte[] iv) {
        try {
            Cipher cipher = Cipher.getInstance(model);
            if (iv != null) {
                IvParameterSpec ivPs = new IvParameterSpec(iv);
                cipher.init(2, getKey(password), ivPs);
            } else {
                cipher.init(2, getKey(password));
            }
            byte[] result = cipher.doFinal(content);
            return new String(result, charset);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static SecretKeySpec getKey(String password) throws Exception {
        SecretKeySpec key = new SecretKeySpec(password.getBytes("UTF-8"), "AES");
        return key;
    }

    public static String fixPassword16(String password) throws Exception {
        System.out.println("password:" + password);
        if (password == null || password.length() == 0) {
            throw new Exception("密码为空");
        }
        if (password.length() > 16) {
            throw new Exception("密码超过16位");
        }
        password = password + StringUtils.getRepeatStrs("0", 16 - password.length());
        return password;
    }
}
